<?php
namespace App\Logic\Storage;

use App\Models\Basics\SysArea;
use App\Models\Inventory\InventoryCn;
use App\Models\Inventory\Transfer;
use App\Models\Stocking\StockingSku;
use Illuminate\Support\Facades\DB;
class TempInventory
{
    public static function exe(){
        try{
            $areaTempId = SysArea::getSysAreaIdByArea('TEMP'); //TEMP站点
            $inventoryTemp = InventoryCn::query()
                ->where('area_id',$areaTempId)
                ->where('area_transit','>',0)
                ->get();
            $areaPublicId = SysArea::getSysAreaIdByArea(); //PUBLIC站点
            $i = 0;
            $num = 100;
            while(true){
                if($inventoryTemp->isEmpty())break;
                $_inventoryTemp = $inventoryTemp->splice($i,$num);
                foreach($_inventoryTemp as $item){
                    DB::beginTransaction();
                    $inventoryPublic = InventoryCn::query()
                        ->where('area_id', $areaPublicId)
                        ->where('psku_id', $item->psku_id)
                        ->where('instant','>',0)
                        ->lockForUpdate()
                        ->first();
                    if(!$inventoryPublic){
                        DB::rollBack();
                        continue;
                    }
                    $tempNum = min($item->area_transit,$inventoryPublic->instant);
                    $inventoryArea = InventoryCn::query()
                        ->select('*',DB::raw('(instant+area_transit) AS totalInventory'))
                        ->whereNotIn('area_id', [$areaPublicId,$areaTempId])
                        ->where('psku_id', $item->psku_id)
                        ->orderByDesc('totalInventory')
                        ->lockForUpdate()
                        ->first();
                    if(!$inventoryArea){
                        $item->instant += $tempNum;
                    }else{
                        $inventoryArea->instant += $tempNum;
                        $flag1 = $inventoryArea->save();
                        if(!$flag1){
                            DB::rollBack();
                            continue;
                        }
                    }
                    $item->area_transit -= $tempNum;
                    $flag2 = $item->save();
                    if(!$flag2){
                        DB::rollBack();
                        continue;
                    }
                    $inventoryPublic->instant -= $tempNum;
                    $flag3 = $inventoryPublic->save();
                    if(!$flag3){
                        DB::rollBack();
                        continue;
                    }
                    //挪用记录
                    $transfer1 = Transfer::query()->create(
                        [
                            'psku_id' => $item->psku_id,
                            'iuser_id' => 1,
                            'iarea_id' => $areaTempId,
                            'ouser_id' => 1,
                            'oarea_id' => $areaPublicId,
                            'deduct_transit' => 1,
                            'transfer_num' => $tempNum,
                            'status' => 2,
                        ]
                    );
                    if(!$transfer1){
                        DB::rollBack();
                        continue;
                    }
                    if($inventoryArea){
                        $transfer2 = Transfer::query()->create(
                            [
                                'psku_id' => $item->psku_id,
                                'iuser_id' => 1,
                                'iarea_id' => $inventoryArea->area_id,
                                'ouser_id' => 1,
                                'oarea_id' => $areaTempId,
                                'transfer_num' => $tempNum,
                                'status' => 2,
                            ]
                        );
                        if($transfer2){
                            StockingSku::upCnInstant($inventoryArea->area_id.'_'.$item->psku_id);
                            DB::commit();
                        }else{
                            DB::rollBack();
                        }
                    }else{
                        DB::commit();
                    }
                }
            }
        }catch (\Exception $e){
            report($e);
        }
    }
}
